home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mint96sb.zoo / doc / ptracer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-31  |  5.4 KB  |  183 lines

  1. /*
  2.  * sample program for demonstrating the debugging calls
  3.  * Written by Alex Kiernan
  4.  */
  5.  
  6. #include <mintbind.h>
  7. #include <stddef.h>
  8.  
  9. typedef struct _context {
  10.     long    regs[15];    /* registers d0-d7, a0-a6 */
  11.     long    usp;        /* user stack pointer (a7) */
  12.     short    sr;        /* status register */
  13.     long    pc;        /* program counter */
  14.     long    ssp;        /* supervisor stack pointer */
  15.     long    term_vec;    /* GEMDOS terminate vector (0x102) */
  16. /*
  17.  * AGK: if running on a TT and the user is playing with the FPU then we
  18.  * must save and restore the context. We should also consider this for
  19.  * I/O based co-processors, although this may be difficult due to
  20.  * possibility of a context switch in the middle of an I/O handshaking
  21.  * exchange.
  22.  */
  23.     unsigned char    fstate[216];    /* FPU internal state */
  24.     long    fregs[3*8];    /* registers fp0-fp7 */
  25.     long    fctrl[3];    /* FPCR/FPSR/FPIAR */
  26. /*
  27.  * AGK: for long (time-wise) co-processor instructions (FMUL etc.), the
  28.  * FPU returns NULL, come-again with interrupts allowed primitives. It
  29.  * is highly likely that a context switch will occur in one of these if
  30.  * running a mathematically intensive application, hence we must handle
  31.  * the mid-instruction interrupt stack. We do this by saving the extra
  32.  * 3 long words and the stack format word here.
  33.  */
  34.     unsigned short    sfmt;    /* stack frame format identifier */
  35.     short    internal[42];    /* internal state -- see framesizes[] for size */
  36.     char    ptrace;        /* trace exception is pending */
  37. } CONTEXT;
  38.  
  39. #define PPROCADDR    (('P'<< 8) | 1)
  40. #define PBASEADDR    (('P'<< 8) | 2)
  41. #define PCTXTSIZE    (('P'<< 8) | 3)
  42. #define PSETFLAGS    (('P'<< 8) | 4)
  43. #define PGETFLAGS    (('P'<< 8) | 5)
  44. #define PTRACESFLAGS    (('P'<< 8) | 6)
  45. #define PTRACEGFLAGS    (('P'<< 8) | 7)
  46. #    define    P_ENABLE    (1 << 0)    /* enable tracing */
  47. #ifdef NOTYETDEFINED
  48. #    define    P_DOS        (1 << 1)    /* trace DOS calls - unimplemented */
  49. #    define    P_BIOS        (1 << 2)    /* trace BIOS calls - unimplemented */
  50. #    define    P_XBIOS        (1 << 3)    /* trace XBIOS calls - unimplemented */
  51. #endif
  52.  
  53. #define PTRACEGO    (('P'<< 8) | 8)    /* these 4 must be together */
  54. #define PTRACEFLOW    (('P'<< 8) | 9)
  55. #define PTRACESTEP    (('P'<< 8) | 10)
  56. #define PTRACE11    (('P'<< 8) | 11)
  57.  
  58. /* lseek() origins */
  59. #define    SEEK_SET    0        /* from beginning of file */
  60. #define    SEEK_CUR    1        /* from current location */
  61. #define    SEEK_END    2        /* from end of file */
  62.  
  63. #define WNOHANG     1
  64. #define WUNTRACED    2
  65.  
  66. /* these definitions are incompatible with <sys/wait.h> */
  67. #define WIFEXITED(x)    ((int)((x) & 0xFF00) == 0)
  68. #define WEXITSTATUS(x)    ((int)((x) & 0xFF))
  69.  
  70. #define WIFSIGNALED(x)    (((int)((x) & 0xFF00) > 0) && ((int)(((x) & 0xFF) == 0)))
  71. #define WTERMSIG(x)    ((int)(((x) & 0xFF00) >> 8))
  72.  
  73. #define WIFSTOPPED(x)    (((int)((x) & 0xFF) == 0x7F) && ((int)(((x) >> 8) & 0xFF) != 0))
  74. #define WSTOPSIG(x)    ((int)(((x) >> 8) & 0xFF))
  75.  
  76. #define SIGTRAP        5        /* trace trap */
  77.  
  78. void
  79. dumpCTXT(ctxt)
  80.     CONTEXT *ctxt;
  81. {
  82.     int i, j;
  83.  
  84.     for (i = 0; i < 16; i += 4) {
  85.         for (j = 0; j < 4; j++) {
  86.             /* oh dear... we output too many commas - c'est la vie */
  87.             printf("%c%d=$%08lx, ", i < 8 ? 'D' : 'A',
  88.               i + j - (i >= 8 ? 8 : 0),
  89.               ctxt[0].regs[i + j]);
  90.         }
  91.         putchar('\n');
  92.     }
  93.     printf("SR=$%04x\n", ctxt[0].sr);
  94.     printf("PC=$%08lx\n", ctxt[0].pc);
  95.     printf("SSP=$%08lx\n", ctxt[0].ssp);
  96.     printf("term_vec=$%08lx\n", ctxt[0].term_vec);
  97.     printf("fstate[0]=%u\n", ctxt[0].fstate[0]);
  98.     for (i = 0; i < 8; i++) {
  99.         printf("FP%d=$%08lx%08lx%08lx\n",
  100.           i,
  101.           ctxt[0].fregs[i * 3 + 0],
  102.           ctxt[0].fregs[i * 3 + 1],
  103.           ctxt[0].fregs[i * 3 + 2]);
  104.     }
  105.     printf("frame format=%u\n", ctxt[0].sfmt >> 12);
  106.     printf("vector offset=$%x\n", ctxt[0].sfmt & 0xfff);
  107.     /* could print internal state here internal[0..41] */
  108. }
  109.  
  110. int
  111. main(argc,argv)
  112.     int argc;
  113.     char *argv[];
  114. {
  115.     int pid;
  116.     unsigned long status;
  117.     int fd;
  118.     char fpid[13];
  119.     CONTEXT ctxt;
  120.     long pctxt;
  121.     long sizeof_ctxt;
  122.     unsigned short sig;
  123.     
  124.     if (isdigit(*argv[1])) {
  125.         pid = atoi(argv[1]);
  126.         sprintf(fpid, "U:\\PROC\\.%03d", pid);
  127.         fd = Fopen(fpid, 0);
  128.         sig = 1;
  129.         Fcntl(fd, (long)&sig, PTRACESFLAGS);    /* capture it */
  130.         Pkill(pid, SIGTRAP);        /* and stop it */
  131.     }
  132.     else {
  133.         pid = Pexec(0x8000 | 100, argv[1], "\0", NULL);
  134.         /* check pid */
  135.         printf("pid = %d\n", pid);
  136.         sprintf(fpid, "U:\\PROC\\.%03d", pid);
  137.         fd = Fopen(fpid, 0);
  138.     }
  139.     /* check fd */
  140.     Fcntl(fd, (long)&pctxt, PPROCADDR);
  141.     Fcntl(fd, (long)&sizeof_ctxt, PCTXTSIZE);
  142.     pctxt -= 2 * sizeof_ctxt;
  143.  
  144.     do {
  145.         status = Pwait3(WUNTRACED, NULL);
  146.         if (WIFSTOPPED(status)) {
  147.             printf("pid = %d\, WSTOPSIG = %d\n", (int)(status >> 16), WSTOPSIG(status));
  148.             Fseek((long)pctxt, fd, SEEK_SET);
  149.             Fread(fd, sizeof(ctxt), &ctxt);    /* note _not_ sizeof_ctxt */
  150.             dumpCTXT(&ctxt);
  151.             switch (Cconin() & 0xff) {
  152.                 case 's':
  153.                 case 'S':
  154.                     Fcntl(fd, (long)NULL, PTRACESTEP);    /* single step */
  155.                     break;
  156.                     
  157.                 case 'g':
  158.                 case 'G':
  159.                     Fcntl(fd, (long)NULL, PTRACEGO);    /* go */
  160.                     break;
  161.                     
  162.                 case 'f':
  163.                 case 'F':
  164.                     Fcntl(fd, (long)NULL, PTRACEFLOW);    /* go to flow change */
  165.                     break;
  166.                     
  167.                 case 'x':
  168.                 case 'X':
  169.                     sig = WSTOPSIG(status);
  170.                     Fcntl(fd, (long)&sig, PTRACEGO);    /* kill it */
  171.                     break;
  172.             }
  173.         }
  174.         putchar('\n');
  175.     } while (!WIFEXITED(status) && !WIFSIGNALED(status));
  176.     if (WIFEXITED(status))
  177.         printf("pid = %d, WEXITSTATUS = %d\n", (int)(status >> 16), WEXITSTATUS(status));
  178.     else
  179.         printf("pid = %d, WTERMSIG = %d\n", (int)(status >> 16), WTERMSIG(status));
  180.     Fclose(fd);    /* but the process is dead... (Jim!) */
  181.     return 0;
  182. }
  183.